﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace NonBinaryTree
{
    public partial class Form1 : Form
    {
        Folder rootFolder = new Folder("C:",null);
        NonBinaryTree<Folder> folderTree = new NonBinaryTree<Folder>();
        Folder mover = new Folder("", null);
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            folderTree.RootNode = rootFolder;

            #region Inserção de Nós

            try
            {
                Folder no1 = new Folder("Documents and Settings", rootFolder);
                rootFolder.Children.Add(no1,c => c.Name == no1.Name);

                Folder no11 = new Folder("Utilizador", no1);
                no1.Children.Add(no11, c => c.Name == no11.Name);

                Folder no111 = new Folder("Ambiente de Trabalho", no11);
                no11.Children.Add(no111, c => c.Name == no111.Name);

                Folder no2 = new Folder("Program Files", rootFolder);
                rootFolder.Children.Add(no2, c => c.Name == no2.Name);
                
                //NonBinaryTreeNodeList<Folder> lista = new NonBinaryTreeNodeList<Folder>();
                //lista.Add(no1);
                //lista.Add(no11);
                //lista.Add(no111);
                //lista.Add(no2);

                //rootFolder.Children.AddRange(lista);

                Folder no3 = new Folder("Windows", rootFolder);
                rootFolder.Children.Add(no3, c => c.Name == no3.Name);
            }
            catch (ArgumentException)
            {
                MessageBox.Show("Nome já existente");
            }

            #endregion

            #region Carregar Listbox e definir Value/Display Member

            refreshListbox(rootFolder, 0);
            listBox1.DisplayMember = "Name";
            listBox1.ValueMember = "Parent";

            #endregion

        }

        #region Botões

        private void btAdicionar_Click(object sender, EventArgs e)
        {
            try
            {
                if (textPasta.Text != "")
                {
                    if (listBox1.SelectedIndex >= 0)
                    {
                        Folder ola = new Folder(textPasta.Text.ToString(), (Folder)listBox1.SelectedItem);
                        Folder add = (Folder)listBox1.SelectedItem;
                        add.Children.Add(ola, c => c.Name.Substring(c.Name.IndexOf("└ ") + 2, c.Name.Length - c.Name.IndexOf("└ ") - 2).Trim() == ola.Name.Trim());
                        //listBox1.Items.Add(ola);
                        listBox1.Items.Clear();
                        refreshListbox(rootFolder, 0);
                        textPasta.Text = "";
                    }
                    else
                    {
                        MessageBox.Show("Deve seleccionar o sitio para inserir a pasta");
                    }
                }
                else
                {
                    MessageBox.Show("Não é possível adicionar pastas sem nome");
                    textPasta.Focus();
                }
            }
            catch (ArgumentException)
            {
                MessageBox.Show("Nome já existente");
            }
        }

        private void btMudar_Click(object sender, EventArgs e)
        {
            try
            {
                if (textPasta.Text != "")
                {
                    bool existe = false;
                    Folder renomear = (Folder)listBox1.SelectedItem;
                    if (renomear.Parent != null)
                    {
                        foreach (Folder f in renomear.Parent.Children)
                        {
                            if (f.Name.Substring(f.Name.IndexOf("└ ") + 2, f.Name.Length - f.Name.IndexOf("└ ") - 2).Trim() == textPasta.Text.Trim())
                            {
                                existe = true;
                            }
                        }

                        if (existe == false)
                        {
                            renomear.Name = textPasta.Text;
                            listBox1.Items.Clear();
                            refreshListbox(rootFolder, 0);
                        }
                        else
                        {
                            MessageBox.Show("Já existe uma pasta com esse nome no directório seleccionado");
                        }
                    }
                    else
                    {
                        MessageBox.Show("Não é possível renomar a pasta raíz");
                    }
                }
                else
                {
                    MessageBox.Show("Não é possível existirem pastas sem nome");
                }
            }
            catch (ApplicationException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btPesquisar_Click(object sender, EventArgs e)
        {
            if (textPasta.Text != "")
            {
                label1.Text = "";
                NonBinaryTreeNodeList<Folder> xv = folderTree.FindAllNodes(c => c.Name.Substring(c.Name.IndexOf("└ ")+2, c.Name.Length - c.Name.IndexOf("└ ")-2).Trim() == textPasta.Text.Trim());
                if (xv == null)
                {
                    MessageBox.Show("Pasta não encontrada");
                }
                else
                {
                    String caminhoPasta = "";
                    foreach (Folder f in xv)
                    {

                        Folder caminho = f;
                        caminhoPasta = caminho.Parent.Name + "\n" + caminhoPasta + "\n";
                        caminho = f.Parent;
                        
                    }
                    MessageBox.Show("Pasta encontrada. Caminho: \n" + caminhoPasta.Trim());
                    //String caminhoPasta = "";
                    //Folder caminho = xv;
                    //while (caminho.Parent != null)
                    //{
                    //    caminhoPasta = caminho.Parent.Name + "\n" + caminhoPasta + "\n";
                    //    caminho = caminho.Parent;
                    //}
                    //MessageBox.Show("Pasta encontrada. Caminho: \n" + caminhoPasta.Trim());
                }
            }
        }

        private void btApagar_Click(object sender, EventArgs e)
        {
            Folder apagar = (Folder)listBox1.SelectedItem;
            if (apagar.Name == folderTree.RootNode.Name)
            {
                MessageBox.Show("Não pode apagar a raíz");
            }
            else
            {
                try
                {
                    Folder xParent = ((Folder)listBox1.SelectedItem).Parent;
                    xParent.Children.RemoveAt(xParent.Children.FindIndex(c => c.Name == ((Folder)listBox1.SelectedItem).Name));
                    listBox1.Items.Clear();
                    refreshListbox(rootFolder, 0);
                }
                catch (ApplicationException ex)
                {
                    MessageBox.Show(ex.Message);
                }
                catch (IndexOutOfRangeException ex1)
                {
                    MessageBox.Show(ex1.Message);
                }
            }
        }


        #endregion

        #region Metodos

        private void refreshListbox(Folder root, int level)
        {
            root.Name = root.Name.TrimStart();
            if (root.Name.Substring(0, 1) == "└")
                root.Name = root.Name.Substring(1, root.Name.Length - 1);

            root.Name = root.Name.TrimStart();
            root.Name = String.Format("{0}{1}{2}", String.Empty.PadLeft(level * 5), "└ ", root.Name);
            listBox1.Items.Add(root);

            ++level;
            foreach (Folder f in root.Children)
            {
                refreshListbox(f, level);
            }
        }

        #endregion

        private void btMover_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedIndex == -1)
            {
                MessageBox.Show("Selecione o nó a mover");
            }
            else
            {
                mover = (Folder)listBox1.SelectedItem;
                listBox1.SelectedIndex = -1;
            }
        }

        private void btConfirmar_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedIndex == -1)
            {
                MessageBox.Show("Selecione a nova pasta par o nó");
            }
            else
            {
                //mover.Parent.Children.Remove(mover);
                Folder destino = (Folder)listBox1.SelectedItem;
                mover.Parent = destino;
                //destino.Children.Add(mover);
                listBox1.SelectedIndex = -1;
                listBox1.Items.Clear();
                refreshListbox(rootFolder, 0);
            }
        }
    }
}
